<template>
  <div v-if="isAdd || isEdit" class="add-inspect-task">
    <px-button style="margin: 16px 0" type="primary" icon="ArrowLeft" @click="backMainPage">返回</px-button>
    <div class="view-flex">
      <div class="add-inspect-task-wrapper">
        <px-scrollbar ref="scrollbarRef" class="add-inspect-task-content" @scroll="handleScroll">
          <px-form ref="formRef" :inline="false" :model="formValue" :rules="rules" label-position="right" label-width="110px">
            <div ref="basicsRef">
              <EditDropDown dropdownTitle="基本信息" style="margin-top: 0">
                <template v-slot:content>
                  <div class="block w-[100%]">
                    <px-row :gutter="16">
                      <px-col :span="12">
                        <px-form-item label="巡检任务编号" prop="taskNo">
                          <px-input v-model="formValue.taskNo" disabled />
                        </px-form-item>
                      </px-col>
                      <px-col :span="12">
                        <px-form-item label="巡检任务名称" prop="taskName">
                          <px-input
                            v-model="formValue.taskName"
                            placeholder="请输入巡检任务名称"
                            maxlength="50"
                            clearable
                            @blur="formValue.taskName = $event.target.value.trim()"
                          />
                        </px-form-item>
                      </px-col>
                    </px-row>
                    <px-row :gutter="16">
                      <px-col :span="12">
                        <!-- 地块 -->
                        <FactoryArea :factoryArea="formValue.factoryAreaCode" :isRequired="true" @changeFactoryArea="changeFactoryArea" />
                      </px-col>
                      <px-col :span="12">
                        <px-form-item label="任务分配" prop="checkGroupCode">
                          <px-select v-model="formValue.checkGroupCode" clearable filterable placeholder="请选择巡检组" style="width: 100%">
                            <px-option v-for="item in checkGroupList" :key="item.id" :label="item.name" :value="item.code" />
                          </px-select>
                        </px-form-item>
                      </px-col>
                    </px-row>
                    <!-- <px-row :gutter="16">
                      <px-col :span="12">
                        <px-form-item label="建议工作天数" prop="recommendDay">
                          <px-input-number v-model="formValue.recommendDay" placeholder="请输入建议工作天数" :min="1" :max="999" />
                        </px-form-item>
                      </px-col>
                    </px-row> -->
                    <px-row :gutter="16">
                      <px-col :span="24">
                        <px-form-item label="说明" prop="description">
                          <px-input v-model="formValue.description" placeholder="请输入巡检任务说明信息" type="textarea" clearable />
                        </px-form-item>
                      </px-col>
                    </px-row>
                  </div>
                </template>
              </EditDropDown>
            </div>
            <div ref="contentRef">
              <EditDropDown dropdownTitle="巡检内容">
                <template v-slot:content>
                  <div class="block w-[100%]">
                    <px-row>
                      <px-col :span="12">
                        <px-form-item label="巡检区域" prop="inspectArea" :rules="{ required: true, message: '请选择巡检区域', trigger: 'change' }">
                          <px-cascader
                            ref="cascaderRef"
                            v-model="formValue.inspectArea"
                            filterable
                            clearable
                            style="width: 100%"
                            :options="positionCodesList"
                            :props="cascaderProps"
                            placeholder="请选择巡检区域"
                            collapse-tags
                            collapse-tags-tooltip
                            @focus="focusPositionCodes"
                            @change="changeCheckArea"
                          />
                        </px-form-item>
                      </px-col>
                      <px-col :span="12">
                        <px-form-item label="巡检内容" prop="checkType" :rules="{ required: true, message: '请选择巡检内容', trigger: 'change' }">
                          <px-radio-group v-model="formValue.checkType" @change="changeInspectContentTypes">
                            <px-radio v-for="item in INSPECT_CONTENT" :key="item.value" :label="item.value">{{ item.label }}</px-radio>
                          </px-radio-group>
                        </px-form-item>
                      </px-col>
                    </px-row>
                    <px-row :gutter="16">
                      <px-col :span="24">
                        <px-form-item label="巡检规则" prop="tableData" class="_form-rules">
                          <px-button type="primary" ghost class="mb-[10px]" @click="handleSelectRules">选择巡检规则</px-button>
                          <InspectRulesTable :table-data="tableData" :tableColumns="tableColumns" :total="0" class="w-[100%]" @del="deleteSelected" />
                        </px-form-item>
                      </px-col>
                    </px-row>
                  </div>
                </template>
              </EditDropDown>
            </div>
            <div ref="periodRef">
              <EditDropDown dropdownTitle="执行周期">
                <template v-slot:content>
                  <ExecutionCycle :form-value="formValue" @change="handelExecutionCycleChange" />
                </template>
              </EditDropDown>
            </div>
            <div ref="equipRef">
              <EditDropDown dropdownTitle="巡检设备" v-if="formValue.checkType === 'equipment'">
                <template v-slot:content>
                  <div class="w-[100%]">
                    <px-row :gutter="16">
                      <px-col :span="24">
                        <px-button type="primary" ghost class="mb-[10px]" @click="handleSelectEquip">选择设备</px-button>
                        <px-form-item
                          label-width="0px"
                          label=""
                          prop="taskEqpRelationDTOS"
                          :rules="[
                            {
                              required: true,
                              validator: validateEqpTable,
                              trigger: 'change'
                            }
                          ]"
                        >
                          <InspectRulesTable
                            :table-data="tableEqiupSelected"
                            :tableColumns="tableEqiupColums"
                            :total="0"
                            :hasDrag="true"
                            class="w-[100%]"
                            @on-drag="tableEqiupDrag"
                            @del="deleteEquipSelected"
                          />
                        </px-form-item>
                      </px-col>
                    </px-row>
                  </div>
                </template>
              </EditDropDown>
            </div>
          </px-form>
        </px-scrollbar>
        <div class="info-form-btns">
          <px-button @click="backMainPage">取消</px-button>
          <!-- <px-button type="primary" ghost @click="handleDraft(formRef)">保存草稿</px-button> -->
          <px-button type="primary" @click="handleSubmit(formRef)">发布巡检任务</px-button>
        </div>
      </div>
      <WidgetRouter :router-list="routerList" :scrollbar-ref="scrollbarRef" :scroll-top="scrollTop" />
    </div>
    <SelectInspectRules
      v-model:is-view="isDialogView"
      :facCode="formValue.factoryAreaCode"
      :checkTypes="[formValue.checkType]"
      :eqpTypeCodes="formValue.checkArea"
      @select-items="selectTreeItems"
    />
    <SelectInspectEquip
      v-model:is-view="isAddEquip"
      :checkArea="formValue.checkArea"
      :facCode="formValue.factoryAreaCode"
      :typeCodeList="typeCodeList"
      @select-items="selectEquipItems"
    />
  </div>
</template>
<script setup lang="ts">
import { getGroupList, queryCheckAreaTree } from "@/api/erc/inspectPlan";
import { checkTaskSave, getTaskNo } from "@/api/erc/inspectTask";
import { useBeforeRouteLeave } from "@/hooks/useBeforeRouteLeave";
import EditDropDown from "@/views/all/equip/components/EditDropDown.vue";
import { debounce } from "@pureadmin/utils";
import { PxMessage, PxMessageBox } from "px-ui";
import { computed, onBeforeMount, reactive, ref, watch, watchEffect } from "vue";
import { FactoryArea, WidgetRouter } from "../../components/index";
import { INSPECT_CONTENT } from "../../config";
import ExecutionCycle from "./ExecutionCycle.vue";
import InspectRulesTable from "./InspectRulesTable.vue";
import SelectInspectEquip from "./SelectInspectEquip.vue";
import SelectInspectRules from "./SelectInspectRules.vue";

import { TableItem } from "../../types";
const cascaderProps = {
  children: "children",
  label: "name",
  value: "id",
  // checkStrictly: true,
  multiple: true
};
const tableColumns = ref<TableItem[]>([
  { prop: "expend", minWidth: "55", fixed: "left" },
  { prop: "checkRuleNo", label: "规则编号", minWidth: "160", showOverflowTooltip: true, fixed: "left" },
  { prop: "checkRuleName", label: "巡检规则名称", minWidth: "160", showOverflowTooltip: true },
  { prop: "facName", label: "地块", minWidth: "160", showOverflowTooltip: true },
  { prop: "eqpTypeName", label: "设备类型", minWidth: "160", showOverflowTooltip: true },
  { prop: "ruleTypeName", label: "规则类型", minWidth: "160", showOverflowTooltip: true },
  // { prop: "recommendDay", label: "建议工作天数", minWidth: "160", showOverflowTooltip: true },
  { prop: "operate", minWidth: "55", label: "操作", showOverflowTooltip: true, fixed: "right" }
]);

const tableEqiupColums = ref<TableItem[]>([
  { prop: "drag", minWidth: "60" },
  { prop: "eqpId", label: "设备编号", minWidth: "160", showOverflowTooltip: true, fixed: "left" },
  { prop: "eqpName", label: "设备名称", minWidth: "160", showOverflowTooltip: true, fixed: "left" },
  { prop: "eqpSys", label: "设备系统", minWidth: "160", showOverflowTooltip: true },
  { prop: "typeName", label: "设备类型", minWidth: "160", showOverflowTooltip: true },
  { prop: "specification", label: "设备型号", minWidth: "160", showOverflowTooltip: true },
  { prop: "positionName", label: "位置信息", minWidth: "160", showOverflowTooltip: true },
  { prop: "operate", minWidth: "55", label: "操作", showOverflowTooltip: true, fixed: "right" }
]);
const props = defineProps(["defaultData"]);
const isMain = defineModel("isMain");
const isAdd = defineModel("isAdd");
const isEdit = defineModel("isEdit");
const taskNo = defineModel("taskNo");
const emits = defineEmits(["refresh"]);
const typeCodeList = computed(() => {
  const arr = tableData.value.filter(item => item.checkType === "equipment");
  const typeAll = arr.reduce((pre, cur) => {
    return [...pre, cur.eqpTypeCode];
  }, []);
  return Array.from(new Set(typeAll));
});
//form表单相关
const formRef = ref();
let formDataTmpl = {
  taskNo: "",
  taskName: "",
  factoryAreaCode: "",
  checkGroupCode: "",
  taskStatus: 1,
  taskType: 2,
  startTime: "",
  endTime: "",
  description: "",
  inspectArea: [],
  taskEqpRelationDTOS: [],
  checkTaskRuleNoList: []
};
// const formValue = ref(cloneDeep(formDataTmpl));
const { setMessage, isFormDirty, formValue, setIsFormDirty, printFormValue, setDefaultValue } = useBeforeRouteLeave({
  defaultValue: formDataTmpl
});
const validateRulesTable = (rule: any, value: any, callback: any) => {
  if (!tableData.value || tableData.value?.length === 0) {
    callback(new Error("请选择巡检规则"));
  } else {
    callback();
  }
};
const validateEqpTable = (rule: any, value: any, callback: any) => {
  if (!tableEqiupSelected.value || tableEqiupSelected.value?.length === 0) {
    callback(new Error("请选择巡检设备"));
  } else {
    callback();
  }
};
const rules = reactive({
  taskNo: [{ required: true, trigger: "blur" }],
  taskName: [
    {
      required: true,
      message: "请输入巡检任务名称",
      trigger: "blur"
    }
  ],
  checkGroupCode: [
    {
      required: true,
      message: "请选择巡检组",
      trigger: "change"
    }
  ],
  tableData: [
    //需要自定义规则
    {
      required: true,
      validator: validateRulesTable,
      trigger: "change"
    }
  ],
  // taskEqpRelationDTOS: [
  //   {
  //     required: true,
  //     validator: validateEqpTable,
  //     trigger: "change"
  //   }
  // ],
  execType: [
    //需要自定义规则
    {
      required: true,
      message: "请选择执行方式",
      trigger: "change"
    }
  ],
  startTime: [
    //需要自定义规则
    {
      required: true,
      message: "请选择开始时间",
      trigger: "change"
    }
  ],
  endTime: [
    //需要自定义规则
    {
      required: true,
      message: "请选择结束时间",
      trigger: "change"
    }
  ],
  execDuration: [
    {
      required: true,
      message: "请选择执行时长",
      trigger: "blur"
    }
  ],
  taskCreateTime: [
    {
      required: true,
      message: "请选择任务生成并提醒时间",
      trigger: "blur"
    }
  ]
});
const checkGroupList = ref([]); //任务分配下拉

const isAddEquip = ref(false);

const isDialogView = ref(false);
//折叠面板ref
const basicsRef = ref(null);
const contentRef = ref(null);
const periodRef = ref(null);
const equipRef = ref(null);
//右侧滚动导航
const scrollbarRef = ref(null);
const routerList = ref([]);
const scrollTop = ref();
// 巡检规则table
const tableData = ref([]);
//选择设备table
const tableEqiupSelected = ref([]);
watchEffect(() => {
  if (props.defaultData) {
    formValue.value = props.defaultData.bacicData;
    //!!! 因为后端规则表单和详情规则字段名不一致，在这里做一层转换
    tableData.value = props.defaultData.tableData.map(item => {
      const checkTaskRuleContentList = item.checkTaskRuleContentList.map(checkTaskRuleContentItem => ({
        ...checkTaskRuleContentItem,
        checkRuleContentItemList: checkTaskRuleContentItem.contentItemList
      }));
      const checkRuleContentItem = { ...item, checkRuleContentList: checkTaskRuleContentList };
      return checkRuleContentItem;
    });
    tableEqiupSelected.value = props.defaultData.tableEqiupSelected;
  }
});
const message = ref("");
const initPage = async () => {
  if (isAdd.value) {
    message.value = "内容未保存，确认退出新建巡检任务吗？";

    if (!taskNo.value) {
      const taskNo = await getTaskNo();
      formValue.value.taskNo = taskNo;
      setDefaultValue(formValue.value);

      formRef.value.clearValidate("checkGroupCode");
      formRef.value.clearValidate("factoryAreaCode");
    }
    setIsFormDirty(true);
  } else {
    taskNo.value = null;
    setIsFormDirty(false);
  }
  setMessage(message.value);
};
//查询条件
onBeforeMount(() => {
  initPage();
  scrollInit();
  getGroupListFun();
});
function backMainPage() {
  if (isFormDirty.value) {
    PxMessageBox.confirm(message.value, "提示", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
      draggable: true
    }).then(async () => {
      // 新增任务
      isAdd.value = false;
      isMain.value = true;
      resetForm();
    });
  } else {
    isAdd.value = false;
    isMain.value = true;
    resetForm();
  }
}

// 获取巡检区域
const positionCodesList = ref<any>([]);
const focusPositionCodes = async () => {
  const data = await queryCheckAreaTree({ name: "", facCode: formValue.value.factoryAreaCode });
  positionCodesList.value = data || [];
};
//reset表单
const resetForm = () => {
  if (!formRef?.value) return;
  formRef.value.resetFields();
  // formValue.value = cloneDeep(formDataTmpl);
  formValue.value.checkTaskRuleNoList = [];
  formValue.value.taskEqpRelationDTOS = [];
  tableEqiupSelected.value = [];
  tableData.value = [];
};
//表单提交
async function handleSubmit(formEl) {
  if (!formEl) return;
  printFormValue();
  await formEl.validate(async valid => {
    if (valid) {
      PxMessageBox.confirm("确认发布巡检任务吗？", "提示", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
        draggable: true
      }).then(async () => {
        const { checkType, ...others } = formValue.value;
        await checkTaskSave({ ...others, checkType: checkType ? [checkType] : [] });
        // 返回上一级
        if (isEdit.value) {
          // 修改任务
          isEdit.value = false;
          emits("refresh");
        } else {
          // 新增任务
          isAdd.value = false;
          isMain.value = true;
        }
        // 重置表单
        resetForm();
        PxMessage.success("发布成功");
      });
    }
  });
}
function extractValuesByKey(array, key) {
  const result = [];
  for (const obj of array) {
    if (obj.hasOwnProperty(key)) {
      result.push(obj[key]);
    }
  }
  return result;
}
watch(
  tableData,
  () => {
    if (tableData.value) {
      formValue.value.checkTaskRuleNoList = extractValuesByKey(tableData.value, "checkRuleNo");
    } else {
      formValue.value.checkTaskRuleNoList = [];
    }
  },
  {
    deep: true
  }
);
watch(
  tableEqiupSelected,
  () => {
    if (tableEqiupSelected.value) {
      formValue.value.taskEqpRelationDTOS = tableEqiupSelected.value.map((item, index) => ({
        planNo: item.planNo,
        eqpId: item.eqpId,
        taskNo: formValue.value.taskNo,
        sort: index
      }));
    } else {
      formValue.value.taskEqpRelationDTOS = [];
    }
  },
  {
    deep: true
  }
);
//右侧滚动导航相关函数
const handleScroll = debounce(({ scrollTop: curScrollTop }) => {
  scrollTop.value = curScrollTop;
}, 200);

function scrollInit() {
  let routerName = "基本信息,巡检内容,执行周期,巡检设备";
  let routerRefs = [basicsRef, contentRef, periodRef, equipRef];
  if (!formValue.value.checkType === "equipment") {
    routerName = "基本信息,巡检内容,执行周期";
    routerRefs = [basicsRef, contentRef, periodRef];
  }
  routerList.value = routerName.split(",").map((item, index) => ({ ref: routerRefs[index], name: item }));
}
function tableEqiupDrag(evt) {
  const oldItem = tableEqiupSelected.value[evt.oldIndex];
  tableEqiupSelected.value.splice(evt.oldIndex, 1);
  tableEqiupSelected.value.splice(evt.newIndex, 0, oldItem);
}
// 转换checkArea格式
const cascaderRef = ref();
const changeCheckArea = val => {
  if (val && val.length > 0) {
    // const codes = Array.from(new Set([].concat(...val))).join(",");
    // formValue.value.checkArea = codes;
    formValue.value.checkArea = val
      .map(item => {
        const ind = item.length - 1;
        return item[ind];
      })
      .join(",");
  } else {
    formValue.value.checkArea = "";
  }
  if (formValue.value.checkType === "environment") {
    tableData.value = [];
  }
  tableEqiupSelected.value = [];
};
function changeFactoryArea(val) {
  formValue.value.factoryAreaCode = val;
  tableEqiupSelected.value = [];
  tableData.value = [];
}
function handleSelectRules() {
  if (!formValue.value.factoryAreaCode || !formValue.value.checkType) {
    formRef?.value.validateField("factoryAreaCode");
    formRef?.value.validateField("checkType");
    if (formValue.value.checkType === "environment") {
      formRef?.value.validateField("inspectArea");
    } else {
      formRef?.value.clearValidate("inspectArea");
    }
  } else {
    isDialogView.value = true;
  }
}
const handleSelectEquip = async () => {
  if (!formValue.value.factoryAreaCode || !formValue.value.checkArea || typeCodeList.value.length === 0) {
    formRef?.value.validateField("factoryAreaCode");
    formRef?.value.validateField("inspectArea");
    formRef?.value.validateField("tableData");
  } else {
    isAddEquip.value = true;
  }
};
//巡检规则
function selectTreeItems(val) {
  tableData.value = mergeAndDeduplicate(tableData.value, val, "id");
  if (tableData.value.length > 0) {
    formRef?.value.clearValidate("tableData");
  }
  tableEqiupSelected.value = [];
}
//设备选择

function selectEquipItems(val) {
  tableEqiupSelected.value = mergeAndDeduplicate(tableEqiupSelected.value, val, "id");
  if (tableEqiupSelected.value.length > 0) {
    formRef?.value.clearValidate("taskEqpRelationDTOS");
  }
}

function mergeAndDeduplicate(arr1, arr2, key) {
  const map = new Map();

  // 合并两个数组
  const combinedArray = [...arr1, ...arr2];

  // 遍历合并后的数组，并根据 key 去重
  combinedArray.forEach(item => {
    map.set(item[key], item);
  });

  // 将 Map 转换回数组
  return Array.from(map.values());
}
// 巡检内容改变
const changeInspectContentTypes = val => {
  tableData.value = [];
  tableEqiupSelected.value = [];
  scrollInit();
};
function deleteSelected(row) {
  tableData.value = tableData.value.filter(item => item["id"] !== row["id"]);
  tableEqiupSelected.value = [];
}
function deleteEquipSelected(row) {
  tableEqiupSelected.value = tableEqiupSelected.value.filter(item => item["id"] !== row["id"]);
}
async function getGroupListFun() {
  checkGroupList.value = await getGroupList({ name: "" });
}
const handelExecutionCycleChange = val => {
  Object.assign(formValue.value, val);
};
</script>
<style lang="scss" scoped>
.add-inspect-task {
  // display: flex;
  width: 100%;
  height: calc(100vh - 195px);
  padding: 0 24px 24px;
  background-color: #fff;
  border-radius: 8px;

  ._form-rules {
    :deep(.px-form-item__content) {
      flex-direction: column;
      align-items: flex-start;
    }
  }

  .add-inspect-task-content {
    :deep(.px-form) {
      width: 100%;

      .px-form-item {
        width: 100%;
        margin-right: 0;

        .px-input {
          width: 100%;
        }

        .px-select {
          width: 100%;
        }

        .px-select-v2 {
          width: 100%;
        }

        .px-input-number {
          width: 100%;

          .px-input__inner {
            text-align: left;
          }
        }

        &.is-error {
          .px-input-number {
            .px-input__wrapper {
              border: 1px solid var(--px-color-danger);
              box-shadow: none;
            }
          }
        }
      }
    }

    .equip-table {
      --px-table-border-color: #dfdfdf;

      margin-bottom: 18px;
      font-size: 14px;

      :deep(.px-table__header) {
        thead {
          tr {
            background-color: #e7eefb !important;

            th {
              font-size: 14px;
              font-weight: bold;
              color: #000;
              background-color: #e7eefb !important;
            }
          }
        }
      }

      :deep(.px-input-number) {
        width: 100%;
      }
    }
  }

  &-wrapper {
    flex: 1 1 auto;
    min-width: 500px;
  }

  .info-form-btns {
    position: absolute;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    width: 100%;
    height: 68px;
    padding-right: 24px;
    background: #fff;
    box-shadow: 0 0 10px 0 rgb(0 0 0 / 16%);
  }
}

.view-flex {
  display: flex;
  height: calc(100vh - 275px);
}
</style>
